﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace XNA_Game_Framework
{
	public partial class InputHandler
	{
		public enum MouseButton { LeftButton, RightButton, MiddleButton };

		string name;
		private KeyboardState keyboardState;
		private KeyboardState lastKeyboardState;
		private MouseState mouseState;
		private MouseState lastMouseState;

		public string Name
		{
			get { return name; }
		}

		public KeyboardState KeyBoardState
		{
			get { return keyboardState; }
		}

		public KeyboardState LastKeyBoardState
		{
			get { return lastKeyboardState; }
		}

		public InputHandler(string name)
		{
			this.name = name;
			keyboardState = Keyboard.GetState();
		}

		public void Update()
		{
			lastKeyboardState = keyboardState;
			keyboardState = Keyboard.GetState();

			lastMouseState = mouseState;
			mouseState = Mouse.GetState();

			KeyPressedEvents();
			MouseEvents();
		}

		private void KeyPressedEvents()
		{
			if (KeyPressed(Keys.A))
			{
				OnAKeyPressed(new KeyPressedEventArgs(Keys.A));
				OnKeyPressed(new KeyPressedEventArgs(Keys.A));
			}
			if (KeyPressed(Keys.B))
			{
				OnBKeyPressed(new KeyPressedEventArgs(Keys.B));
				OnKeyPressed(new KeyPressedEventArgs(Keys.B));
			}
			if (KeyPressed(Keys.C))
			{
				OnCKeyPressed(new KeyPressedEventArgs(Keys.C));
				OnKeyPressed(new KeyPressedEventArgs(Keys.C));
			}
			if (KeyPressed(Keys.D))
			{
				OnDKeyPressed(new KeyPressedEventArgs(Keys.D));
				OnKeyPressed(new KeyPressedEventArgs(Keys.D));
			}
			if (KeyPressed(Keys.E))
			{
				OnEKeyPressed(new KeyPressedEventArgs(Keys.E));
				OnKeyPressed(new KeyPressedEventArgs(Keys.E));
			}
			if (KeyPressed(Keys.F))
			{
				OnFKeyPressed(new KeyPressedEventArgs(Keys.F));
				OnKeyPressed(new KeyPressedEventArgs(Keys.F));
			}
			if (KeyPressed(Keys.G))
			{
				OnGKeyPressed(new KeyPressedEventArgs(Keys.G));
				OnKeyPressed(new KeyPressedEventArgs(Keys.G));
			}
			if (KeyPressed(Keys.H))
			{
				OnHKeyPressed(new KeyPressedEventArgs(Keys.H));
				OnKeyPressed(new KeyPressedEventArgs(Keys.H));
			}
			if (KeyPressed(Keys.I))
			{
				OnIKeyPressed(new KeyPressedEventArgs(Keys.I));
				OnKeyPressed(new KeyPressedEventArgs(Keys.I));
			}
			if (KeyPressed(Keys.J))
			{
				OnJKeyPressed(new KeyPressedEventArgs(Keys.J));
				OnKeyPressed(new KeyPressedEventArgs(Keys.J));
			}
			if (KeyPressed(Keys.K))
			{
				OnKKeyPressed(new KeyPressedEventArgs(Keys.K));
				OnKeyPressed(new KeyPressedEventArgs(Keys.K));
			}
			if (KeyPressed(Keys.L))
			{
				OnLKeyPressed(new KeyPressedEventArgs(Keys.L));
				OnKeyPressed(new KeyPressedEventArgs(Keys.L));
			}
			if (KeyPressed(Keys.M))
			{
				OnMKeyPressed(new KeyPressedEventArgs(Keys.M));
				OnKeyPressed(new KeyPressedEventArgs(Keys.M));
			}
			if (KeyPressed(Keys.N))
			{
				OnNKeyPressed(new KeyPressedEventArgs(Keys.N));
				OnKeyPressed(new KeyPressedEventArgs(Keys.N));
			}
			if (KeyPressed(Keys.O))
			{
				OnOKeyPressed(new KeyPressedEventArgs(Keys.O));
				OnKeyPressed(new KeyPressedEventArgs(Keys.O));
			}
			if (KeyPressed(Keys.P))
			{
				OnPKeyPressed(new KeyPressedEventArgs(Keys.P));
				OnKeyPressed(new KeyPressedEventArgs(Keys.P));
			}
			if (KeyPressed(Keys.Q))
			{
				OnQKeyPressed(new KeyPressedEventArgs(Keys.Q));
				OnKeyPressed(new KeyPressedEventArgs(Keys.Q));
			}
			if (KeyPressed(Keys.R))
			{
				OnRKeyPressed(new KeyPressedEventArgs(Keys.R));
				OnKeyPressed(new KeyPressedEventArgs(Keys.R));
			}
			if (KeyPressed(Keys.S))
			{
				OnSKeyPressed(new KeyPressedEventArgs(Keys.S));
				OnKeyPressed(new KeyPressedEventArgs(Keys.S));
			}
			if (KeyPressed(Keys.T))
			{
				OnTKeyPressed(new KeyPressedEventArgs(Keys.T));
				OnKeyPressed(new KeyPressedEventArgs(Keys.T));
			}
			if (KeyPressed(Keys.U))
			{
				OnUKeyPressed(new KeyPressedEventArgs(Keys.U));
				OnKeyPressed(new KeyPressedEventArgs(Keys.U));
			}
			if (KeyPressed(Keys.V))
			{
				OnVKeyPressed(new KeyPressedEventArgs(Keys.V));
				OnKeyPressed(new KeyPressedEventArgs(Keys.V));
			}
			if (KeyPressed(Keys.W))
			{
				OnWKeyPressed(new KeyPressedEventArgs(Keys.W));
				OnKeyPressed(new KeyPressedEventArgs(Keys.W));
			}
			if (KeyPressed(Keys.X))
			{
				OnXKeyPressed(new KeyPressedEventArgs(Keys.X));
				OnKeyPressed(new KeyPressedEventArgs(Keys.X));
			}
			if (KeyPressed(Keys.Y))
			{
				OnYKeyPressed(new KeyPressedEventArgs(Keys.Y));
				OnKeyPressed(new KeyPressedEventArgs(Keys.Y));
			}
			if (KeyPressed(Keys.Z))
			{
				OnZKeyPressed(new KeyPressedEventArgs(Keys.Z));
				OnKeyPressed(new KeyPressedEventArgs(Keys.Z));
			}
			if (KeyPressed(Keys.Back))
			{
				OnBackSpaceKeyPressed(new KeyPressedEventArgs(Keys.Back));
				OnKeyPressed(new KeyPressedEventArgs(Keys.Back));
			}
			if (KeyPressed(Keys.Down))
			{
				OnDownKeyPressed(new KeyPressedEventArgs(Keys.Down));
				OnKeyPressed(new KeyPressedEventArgs(Keys.Down));
			}
			if (KeyPressed(Keys.Enter))
			{
				OnEnterKeyPressed(new KeyPressedEventArgs(Keys.Enter));
				OnKeyPressed(new KeyPressedEventArgs(Keys.Enter));
			}
			if (KeyPressed(Keys.Escape))
			{
				OnEscKeyPressed(new KeyPressedEventArgs(Keys.Escape));
				OnKeyPressed(new KeyPressedEventArgs(Keys.Escape));
			}
			if (KeyPressed(Keys.Up))
			{
				OnUpKeyPressed(new KeyPressedEventArgs(Keys.Up));
				OnKeyPressed(new KeyPressedEventArgs(Keys.Up));
			}
		}

		private void MouseEvents()
		{
			MouseMovedEvents();
			MousePressedEvents();
			MouseDraggedEvents();
		}

		private void MousePressedEvents()
		{
			if (MouseButtonPressed(MouseButton.LeftButton))
			{
				OnLeftButtonPressed(CurrentMouseEventArgs(MouseButton.LeftButton));
			}
			else if (MouseButtonPressed(MouseButton.RightButton))
			{
				OnRightButtonPressed(CurrentMouseEventArgs(MouseButton.RightButton));
			}
		}

		private void MouseMovedEvents()
		{
			if (mouseState.X != lastMouseState.X || mouseState.Y != lastMouseState.Y)
			{
				OnMouseMoved(CurrentMouseEventArgs(MouseButton.LeftButton));
			}
		}

		private void MouseDraggedEvents()
		{
			if (MouseDragged(MouseButton.LeftButton))
			{
				OnMouseLeftDrag(CurrentMouseEventArgs(MouseButton.LeftButton));
			}
			else if (MouseDragged(MouseButton.RightButton))
			{
				OnMouseRightDrag(CurrentMouseEventArgs(MouseButton.RightButton));
			}
		}

		private bool MouseButtonPressed(MouseButton button)
		{
			if (button == MouseButton.LeftButton)
			{
				return mouseState.LeftButton == ButtonState.Pressed && lastMouseState.LeftButton == ButtonState.Released;
			}
			else if (button == MouseButton.RightButton)
			{
				return mouseState.RightButton == ButtonState.Pressed && lastMouseState.RightButton == ButtonState.Released;
			}
			else if (button == MouseButton.MiddleButton)
			{
				return mouseState.MiddleButton == ButtonState.Pressed && lastMouseState.MiddleButton == ButtonState.Released;
			}
			return false;
		}

		private bool MouseDragged(MouseButton button)
		{
			if (mouseState.X != lastMouseState.X || mouseState.Y != lastMouseState.Y)
			{
				if (button == MouseButton.LeftButton)
				{
					return mouseState.LeftButton == ButtonState.Pressed && lastMouseState.LeftButton == ButtonState.Pressed;
				}
				else if (button == MouseButton.RightButton)
				{
					return mouseState.RightButton == ButtonState.Pressed && lastMouseState.RightButton == ButtonState.Pressed;
				}
			}
			return false;
		}

		private MouseEventArgs CurrentMouseEventArgs(MouseButton button)
		{
			return new MouseEventArgs(button, mouseState.X, mouseState.Y, lastMouseState.X, lastMouseState.Y);
		}

		public bool KeyReleased(Keys key)
		{
			return keyboardState.IsKeyUp(key) && lastKeyboardState.IsKeyDown(key);
		}

		public bool KeyPressed(Keys key)
		{
			return keyboardState.IsKeyDown(key) && lastKeyboardState.IsKeyUp(key);
		}

		public bool KeyDown(Keys key)
		{
			return keyboardState.IsKeyDown(key);
		}
	}
}
